#[derive(Debug, Clone)]
pub enum VMValEnum {
    // VMValNull { val: VMValNull },
    VMValBoolean { val: VMValBoolean },
    VMValChar { val: VMValChar },
    VMValByte { val: VMValByte },
    VMValShort { val: VMValShort },
    VMValInteger { val: VMValInteger },
    VMValLong { val: VMValLong },
    VMValFloat { val: VMValFloat },
    VMValDouble { val: VMValDouble },
    VMValRef { val: VMValRef },
}

#[macro_export]
macro_rules! get_val_from_vm_val_enum {
    ($val:expr, $type:ident) => {
        match $val {
            VMValEnum::$type { val } => { val }
            _ => {
                panic!("{},{},{}", file!(), line!(), "类型异常")
            }
        }
    };
}


impl VMValEnum {
    pub fn convert2integer(val_enum: &VMValEnum) -> VMValInteger {
        match val_enum {
            VMValEnum::VMValByte { val } => {
                VMValInteger { num: val.num as i32 }
            }
            VMValEnum::VMValShort { val } => {
                VMValInteger { num: val.num as i32 }
            }
            VMValEnum::VMValInteger { val } => {
                VMValInteger { num: val.num }
            }
            _ => {
                panic!("{},{},{},{:#?}", file!(), line!(), "类型转化异常", val_enum);
            }
        }
    }

    pub fn convert2double(val_enum: &VMValEnum) -> VMValDouble {
        match val_enum {
            VMValEnum::VMValDouble { val } => {
                VMValDouble { num: val.num }
            }
            _ => {
                panic!("{},{},{},{:#?}", file!(), line!(), "类型转化异常", val_enum);
            }
        }
    }

    pub fn convert2ref(val_enum: &VMValEnum) -> VMValRef {
        match val_enum {
            VMValEnum::VMValRef { val } => {
                VMValRef { num: val.num }
            }
            _ => {
                panic!("{},{},{},{:#?}", file!(), line!(), "类型转化异常", val_enum);
            }
        }
    }
}

// #[derive(Debug, Clone)]
// pub struct VMValNull {}
//
// pub const NULL: VMValNull = VMValNull {};


#[derive(Debug, Clone)]
pub struct VMValBoolean {
    pub val: bool,
}

pub const TRUE: VMValBoolean = VMValBoolean { val: true };
pub const FALSE: VMValBoolean = VMValBoolean { val: false };


#[derive(Debug, Clone)]
pub struct VMValByte {
    pub num: i8,
}

pub const BYTE_ZERO: VMValByte = VMValByte { num: 0 };

#[derive(Debug, Clone)]
pub struct VMValShort {
    pub num: i16,
}

pub const SHORT_ZERO: VMValShort = VMValShort { num: 0 };

#[derive(Debug, Clone)]
pub struct VMValChar {
    pub val: u16,
}


#[derive(Debug, Clone)]
pub struct VMValInteger {
    pub num: i32,
}

pub const INTEGER_ZERO: VMValInteger = VMValInteger { num: 0 };

#[derive(Debug, Clone)]
pub struct VMValLong {
    pub num: i64,
}

pub const LONG_ZERO: VMValLong = VMValLong { num: 0 };

#[derive(Debug, Clone)]
pub struct VMValFloat {
    pub num: f32,
}

pub const FLOAT_ZERO: VMValFloat = VMValFloat { num: 0.0 };

#[derive(Debug, Clone)]
pub struct VMValDouble {
    pub num: f64,
}

pub const DOUBLE_ZERO: VMValDouble = VMValDouble { num: 0.0 };

#[derive(Debug, Clone)]
pub struct VMValRef {
    pub num: usize,
}

pub const NULL_REF: VMValRef = VMValRef { num: usize::MAX };